package order

type tOrderImplement struct {
	state *tOrderHeaderEntity
}

func newOrderImplement(order *tOrderHeaderEntity) IOrder {
	it := new(tOrderImplement)
	it.init(order)
	return it
}

func (me *tOrderImplement) init(order *tOrderHeaderEntity) {
	me.state = order
}

func (me *tOrderImplement) GetHeader() *OrderHeaderDTO {
	return me.state.ToOrderHeader()
}

func (me *tOrderImplement) SaveHeader(it *OrderHeaderDTO) error {
	entity := new(tOrderHeaderEntity)
	entity.Read(it)

	err, entity := MockOrderRepository.SaveOrderHeader(entity)
	if err != nil {
		return err
	}

	me.state = entity
	return nil
}

func (me *tOrderImplement) GetItems() []*OrderItemDTO {
	err, items := MockOrderRepository.LoadOrderItemsByOrderID(me.state.OrderID)
	if err != nil {
		return nil
	}

	lst := make([]*OrderItemDTO, len(items))
	for i, it := range items {
		lst[i] = it.ToOrderItemData()
	}

	return lst
}

func (me *tOrderImplement) AddItem(item *OrderItemDTO) error {
	entity := &tOrderItemEntity{}
	entity.Read(item)
	entity.ItemID = MockOrderRepository.NewItemID()
	entity.OrderID = me.state.OrderID

	return MockOrderRepository.Transaction(func() error {
		// lock header
		err, header := MockOrderRepository.SaveOrderHeader(me.state)
		if err != nil {
			return err
		}
		me.state = header

		// save item
		err, _ = MockOrderRepository.SaveOrderItem(entity)
		return err
	})
}

func (me *tOrderImplement) DelItem(item *OrderItemDTO) error {
	entity := &tOrderItemEntity{}
	entity.Read(item)
	entity.OrderID = me.state.OrderID

	return MockOrderRepository.Transaction(func() error {
		// lock header
		err, header := MockOrderRepository.SaveOrderHeader(me.state)
		if err != nil {
			return err
		}
		me.state = header

		// del item
		return MockOrderRepository.RemoveOrderItem(entity)
	})
}
